/**
 * 基础下载处理器 - 所有下载类型的基类
 */

import ChatHistory from '../ChatHistory.js'

class BaseDownloadHandler {
  
  // 静态属性用于存储待下载信息
  static pendingDownload = null
  static directoryResultCallback = null
  static isNavigating = false
  
  /**
   * 处理通用下载逻辑
   * @param {Object} item 下载项
   * @param {Object} options 下载选项
   */
  static handleDownload(item, options = {}) {
    console.log('处理下载:', item, options)
    
    const itemName = this.getItemName(item)
    const itemType = this.getItemType(item)
    const displayName = this.getDisplayName(item)
    
    // 检查下载链接
    const downloadOptions = this.getDownloadOptions(item)
    if (downloadOptions.length === 0) {
      uni.showToast({
        title: '没有可用的下载链接',
        icon: 'error'
      })
      return
    }
    
    // 显示下载选项
    this.showDownloadOptions(item, downloadOptions, displayName)
  }
  
  /**
   * 显示下载选项
   * @param {Object} item 下载项
   * @param {Array} downloadOptions 下载选项
   * @param {string} displayName 显示名称
   */
  static showDownloadOptions(item, downloadOptions, displayName) {
    if (downloadOptions.length === 1) {
      // 只有一个下载选项，直接显示下载方式选择
      this.showDownloadMethods(item, downloadOptions[0].url, downloadOptions[0].type)
    } else {
      // 多个下载选项，先选择网络类型
      const buttons = downloadOptions.map(option => option.label)
      
      uni.showActionSheet({
        title: `下载《${displayName}》`,
        itemList: buttons,
        success: (res) => {
          const selectedOption = downloadOptions[res.tapIndex]
          this.showDownloadMethods(item, selectedOption.url, selectedOption.type)
        }
      })
    }
  }
  
  /**
   * 显示下载方式选择
   * @param {Object} item 下载项
   * @param {string} downloadUrl 下载链接
   * @param {string} networkType 网络类型
   */
  static showDownloadMethods(item, downloadUrl, networkType = '') {
    const title = networkType ? `选择下载方式（${networkType}）` : '选择下载方式'
    
    uni.showActionSheet({
      title: title,
      itemList: ['下载到默认目录',  '复制下载链接', '查看下载进度'],
      success: (res) => {
        switch (res.tapIndex) {
          case 0:
            this.downloadToDefaultDir(item, downloadUrl)
            break
          case 1:
            this.copyDownloadLink(item, downloadUrl)
            break
          case 2:
            this.navigateToDownloadPage()
            break
        }
      }
    })
  }
  
  /**
   * 下载到默认目录
   * @param {Object} item 下载项
   * @param {string} downloadUrl 下载链接
   */
  static downloadToDefaultDir(item, downloadUrl) {
    const itemName = this.getItemName(item)
    
    uni.showModal({
      title: '确认下载',
      content: `确定要下载《${itemName}》到默认目录吗？`,
      confirmText: '开始下载',
      cancelText: '取消',
      success: (res) => {
        if (res.confirm) {
          setTimeout(() => {
            this.navigateToDownloadPage()
            setTimeout(() => {
              this.startDownload(item, downloadUrl, '默认目录')
            }, 800)
          }, 200)
        }
      }
    })
  }

  
  /**
   * 显示目录选择列表
   * @param {Array} directories 目录列表
   */
  static showDirectoryList(directories) {
    if (!this.pendingDownload) return
    
    const { itemName } = this.pendingDownload
    
    // 准备选项列表（默认目录 + 自定义目录 + 管理选项）
    const options = [
      '📁 使用默认目录',
      ...directories.map(dir => `📂 ${dir.name}`),
      '⚙️ 管理下载目录...'
    ]
    
    uni.showActionSheet({
      title: `选择《${itemName}》的下载目录`,
      itemList: options,
      success: (res) => {
        const selectedIndex = res.tapIndex
        
        if (selectedIndex === 0) {
          // 选择默认目录
          this.startDownloadWithSelectedDirectory('默认目录')
        } else if (selectedIndex === options.length - 1) {
          // 管理目录
          this.navigateToDirectoryManager()
        } else {
          // 选择自定义目录
          const selectedDirectory = directories[selectedIndex - 1]
          console.log('选择的目录:', selectedDirectory)
          
          uni.showToast({
            title: `将下载到: ${selectedDirectory.name}`,
            icon: 'success'
          })
          
          this.startDownloadWithSelectedDirectory(selectedDirectory.path, selectedDirectory)
        }
      },
      fail: () => {
        // 用户取消
        this.pendingDownload = null
      }
    })
  }
  
  /**
   * 跳转到目录管理页面
   */
  static navigateToDirectoryManager() {
    uni.navigateTo({
      url: '/pages/work/mytool/downloads/directories/index',
      success: () => {
        console.log('跳转到目录管理页面成功')
        // 清理待下载信息
        this.pendingDownload = null
      },
      fail: (err) => {
        console.log('跳转失败:', err)
        uni.showToast({
          title: '页面跳转失败',
          icon: 'error'
        })
      }
    })
  }
  
  /**
   * 使用选择的目录开始下载
   * @param {string} selectedDirectory 选择的目录路径
   * @param {Object} directoryInfo 目录信息对象（可选）
   */
  static startDownloadWithSelectedDirectory(selectedDirectory, directoryInfo = null) {
    if (!this.pendingDownload) {
      console.log('没有待下载的任务')
      return
    }
    
    const { item, downloadUrl, itemName } = this.pendingDownload
    
    console.log(`开始下载《${itemName}》到: ${selectedDirectory}`)
    if (directoryInfo) {
      console.log('目录信息:', directoryInfo)
    }
    
    // 清理待下载信息
    this.pendingDownload = null
    
    // 导航到下载页面并开始下载
    setTimeout(() => {
      this.navigateToDownloadPage()
      setTimeout(() => {
        // 开始下载，传递选择的目录信息
        this.startDownload(item, downloadUrl, selectedDirectory, directoryInfo)
      }, 1000)
    }, 500)
  }
  
  /**
   * 复制下载链接
   * @param {Object} item 下载项
   * @param {string} downloadUrl 下载链接
   */
  static copyDownloadLink(item, downloadUrl) {
    const itemName = this.getItemName(item)
    const category = this.getCategory()
    
    this.copyToClipboard(downloadUrl, `${category}下载链接已复制`)
    
    // 记录到聊天历史
    ChatHistory.addMessage({
      type: 'system',
      content: `已复制${category}《${itemName}》的下载链接`,
      sender: 'system',
      category: category.toLowerCase(),
      data: item
    })
  }
  
  /**
   * 复制到剪贴板
   * @param {string} text 要复制的文本
   * @param {string} message 成功提示信息
   */
  static copyToClipboard(text, message = '链接已复制') {
    // #ifdef H5
    if (navigator.clipboard) {
      navigator.clipboard.writeText(text).then(() => {
        uni.showToast({
          title: message,
          icon: 'success'
        })
      }).catch(() => {
        this.fallbackCopyToClipboard(text, message)
      })
    } else {
      this.fallbackCopyToClipboard(text, message)
    }
    // #endif
    
    // #ifndef H5
    uni.setClipboardData({
      data: text,
      success: () => {
        uni.showToast({
          title: message,
          icon: 'success'
        })
      },
      fail: () => {
        uni.showToast({
          title: '复制失败',
          icon: 'error'
        })
      }
    })
    // #endif
  }
  
  /**
   * 请求存储权限
   * @param {Function} callback 权限获取成功回调
   */
  static requestStoragePermission(callback) {
    // #ifdef APP-PLUS
    // 使用全局权限管理工具检查权限
    const PermissionManager = require('../../../../../../utils/permissionManager.js').default
    if (PermissionManager.hasStoragePermission()) {
      console.log('存储权限已获取')
      callback()
      return
    }
    
    // 如果没有权限，则请求权限
    console.log('需要请求存储权限')
    PermissionManager.requestStoragePermission((granted) => {
      if (granted) {
        console.log('存储权限获取成功')
        callback()
      } else {
        console.log('存储权限被拒绝，但仍继续执行')
        callback()
      }
    })
    // #endif
    
    // #ifndef APP-PLUS
    callback()
    // #endif
  }

  
  /**
   * 备用复制方法（H5环境）
   * @param {string} text 要复制的文本
   * @param {string} message 成功提示信息
   */
  static fallbackCopyToClipboard(text, message) {
    const textArea = document.createElement('textarea')
    textArea.value = text
    document.body.appendChild(textArea)
    textArea.select()
    try {
      document.execCommand('copy')
      uni.showToast({
        title: message,
        icon: 'success'
      })
    } catch (err) {
      uni.showToast({
        title: '复制失败，请手动复制',
        icon: 'error'
      })
    }
    document.body.removeChild(textArea)
  }
  
  /**
   * 导航到下载页面
   */
  static navigateToDownloadPage() {
    // 防止重复导航
    if (this.isNavigating) {
      console.log('正在导航中，跳过本次请求')
      return
    }
    
    this.isNavigating = true
    
    uni.navigateTo({
      url: '/pages/work/mytool/downloads/index',
      success: () => {
        console.log('成功跳转到下载页面')
        setTimeout(() => {
          this.isNavigating = false
        }, 1000)
      },
      fail: (err) => {
        console.log('跳转失败:', err)
        this.isNavigating = false
        
        uni.redirectTo({
          url: '/pages/work/mytool/downloads/index',
          success: () => {
            console.log('重定向成功')
          },
          fail: (redirectErr) => {
            console.log('重定向也失败:', redirectErr)
            uni.showToast({
              title: '页面跳转失败',
              icon: 'error'
            })
          }
        })
      }
    })
  }
  
  // ========== 抽象方法，需要子类实现 ==========
  
  /**
   * 获取项目名称
   * @param {Object} item 下载项
   * @returns {string} 项目名称
   */
  static getItemName(item) {
    throw new Error('子类必须实现 getItemName 方法')
  }
  
  /**
   * 获取项目类型
   * @param {Object} item 下载项
   * @returns {string} 项目类型
   */
  static getItemType(item) {
    throw new Error('子类必须实现 getItemType 方法')
  }
  
  /**
   * 获取显示名称
   * @param {Object} item 下载项
   * @returns {string} 显示名称
   */
  static getDisplayName(item) {
    return this.getItemName(item)
  }
  
  /**
   * 获取下载选项
   * @param {Object} item 下载项
   * @returns {Array} 下载选项列表
   */
  static getDownloadOptions(item) {
    throw new Error('子类必须实现 getDownloadOptions 方法')
  }
  
  /**
   * 获取分类名称
   * @returns {string} 分类名称
   */
  static getCategory() {
    throw new Error('子类必须实现 getCategory 方法')
  }
  
  /**
   * 开始下载
   * @param {Object} item 下载项
   * @param {string} downloadUrl 下载链接
   * @param {string} targetDir 目标目录
   */
  static startDownload(item, downloadUrl, targetDir) {
    throw new Error('子类必须实现 startDownload 方法')
  }
}

export default BaseDownloadHandler